文章目录
  1. 1. class文件的内部结构
    1. 1.1. u4 magic
    2. 1.2. u2 minor_version; u2 major_version
    3. 1.3. u2 constant_pool_count; cp_info constant_pool[constant_pool_count-1]
    4. 1.4. u2 access_flags
    5. 1.5. u2 this_class :
    6. 1.6. u2 super_class
    7. 1.7. u2 interfaces_count; u2 interfaces[interfaces_count]; 接口索引集合,用来实现的接口格式以及接口类名
    8. 1.8. u2 fields_count; field_info fields[fields_count];
    9. 1.9. u2 methods_count; method_info methods[methods_count]
    10. 1.10. u2 attributes_count; attribute_info attributes[attributes_count]
      1. 1.10.1. Code属性
      2. 1.10.2. Exceptions属性
      3. 1.10.3. LineNumberTable属性

Class文件是一组以8位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑的排列在Class文件之中,中间没有添加任何分隔符。
根据Java虚拟机的规定,Class文件格式采用一种类似于C语言结构体的伪结构来存储,这种伪结构中只有两种数据类型:五符号数和表。

  • 无符号数属于基本的数据类型:u1、u2、u4、u8来分辨代表1个字节、2个字节、4个字节、8个字节的无符号数。
  • 表是由多个无符号数或其他表作为数据项构成的符合数据类型。

    class文件的内部结构

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    ClassFile { 
    u4 magic;
    u2 minor_version;
    u2 major_version;
    u2 constant_pool_count;
    cp_info constant_pool[constant_pool_count-1];
    u2 access_flags;
    u2 this_class;
    u2 super_class;
    u2 interfaces_count;
    u2 interfaces[interfaces_count];
    u2 fields_count;
    field_info fields[fields_count];
    u2 methods_count;
    method_info methods[methods_count];
    u2 attributes_count;
    attribute_info attributes[attributes_count];
    }

u4 magic

u4 magic是一个固定的值,每个Class文件的头4个字节成为魔数,它的唯一作用是判断这个文件是否为为一个能被虚拟机接受的Class文件,目前值是0xCAFEBABE。

u2 minor_version; u2 major_version

u2 minor_version; u2 major_version代表的是次版本号和主版本号。

u2 constant_pool_count; cp_info constant_pool[constant_pool_count-1]

u2 constant_pool_count; cp_info constant_pool[constant_pool_count-1]; 这里面代表常量池个数以及常量池信息
由于常量池中的数量是不固定的,所以在常量池的入口需要放置一项u2类型的数据,代表常量池容量计数器。
常量池中主要存放两大类常量:字面量和符号引用。
字面量比较接近Java语言层面的常量的概念,如文本字符串、被声明为final的常量值;
符号引用则属于编译原理方面的概念,包括了下面三个类常量:

  • 类和接口的全限定名
  • 字段的名称好描述符
  • 方法的名称和描述符

    u2 access_flags

    u2 access_flags : 类索引,代表class访问标记,这个标志用来标识一些类或接口层次的访问信息,包括这个Class是类还是接口,是否定义为public类型、是否定义为abstract类型等等,例如:public protected

    u2 this_class :

    父索引,代表这个类的名称 例如 java.lang.Object

    u2 super_class

    接口索引结合 : 代表父类名称

    u2 interfaces_count; u2 interfaces[interfaces_count]; 接口索引集合,用来实现的接口格式以及接口类名

    类索引和父索引都是一个u2类型的数据,而接口索引集合是一组u2类型的数据的集合,Class文件中由这三项数据来确定这个类的继承关系。
    类索引用于确定这个类的全限定名;父索引用于确定确定这个类的父类的全限定名。由于Java不支持多继承,所以父类索引只有一个,除了java父索引用于确定确定这个类的父类的全限定名。由于Java不支持多继承,所以父类索引只有一个,除了java.long.Object之外,所有的Java类都有父类,因此除了java.long.Object外,所有Java类的父类索引都不为0。
    接口索引集合用来描述这个类实现了哪些接口。u2 interfaces_count为接口计数器,表示索引表的容量。如果该类没有实现任何接口,那么该计数器为0,后面接口的索引表不会再占用任何字节。

    u2 fields_count; field_info fields[fields_count];

    代表字段个数以及字段信息,用于描述接口或类中声明的变量。

    u2 methods_count; method_info methods[methods_count]

    方法个数以及方法信息

    u2 attributes_count; attribute_info attributes[attributes_count]

    属性表集合,在Class文件、字段表、方法表、中都有可以携带自己的属性表集合。

    Code属性

    Java程序方法体里面的代码经过Javac编译器编译出来之后,最终变为字节码指令存储在Code属性之内。Code属性出现在方法表的属性集合之中,但并非所有的方法表都必须存在这个属性,比如抽象来和接口就不需要。

    Exceptions属性

    列举出方法中可能抛出的异常,也就是方法描述时在throws关键字后面列举的异常。

    LineNumberTable属性

    用于描述Java源代码行号与字节码行号之间的对应关系。
文章目录
  1. 1. class文件的内部结构
    1. 1.1. u4 magic
    2. 1.2. u2 minor_version; u2 major_version
    3. 1.3. u2 constant_pool_count; cp_info constant_pool[constant_pool_count-1]
    4. 1.4. u2 access_flags
    5. 1.5. u2 this_class :
    6. 1.6. u2 super_class
    7. 1.7. u2 interfaces_count; u2 interfaces[interfaces_count]; 接口索引集合,用来实现的接口格式以及接口类名
    8. 1.8. u2 fields_count; field_info fields[fields_count];
    9. 1.9. u2 methods_count; method_info methods[methods_count]
    10. 1.10. u2 attributes_count; attribute_info attributes[attributes_count]
      1. 1.10.1. Code属性
      2. 1.10.2. Exceptions属性
      3. 1.10.3. LineNumberTable属性